package com.kede.app.service.impl;

import cn.hutool.core.img.ImgUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import com.kede.app.ConstKey;
import com.kede.app.domain.Operat;
import com.kede.app.domain.SyWeixToken;
import com.kede.app.repository.OperatRepository;
import com.kede.app.repository.SyWeixTokenRepository;
import com.kede.app.service.OperatService;
import com.kede.app.service.dto.OperatDto;
import com.kede.app.service.dto.OperatQueryCriteria;
import com.kede.app.service.mapstruct.OperatMapper;
import com.kede.config.FileProperties;
import com.kede.utils.FileUtil;
import com.kede.utils.PageUtil;
import com.kede.utils.QueryHelp;
import com.kede.utils.ValidationUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.*;

/**
* @description 服务实现
* @author Pr.li
* @date 2023-08-13
**/
@Service
@RequiredArgsConstructor
public class OperatServiceImpl implements OperatService {

    private final OperatRepository operatRepository;
    private final OperatMapper operatMapper;
    private final FileProperties properties;
    private final SyWeixTokenRepository weixTokenRepository;

    @Value("${htmlImgSrc}")
    private String htmlImgSrc;

    @Value("${xcx.env_version}")
    private String XcxVersion;

    @Override
    public Map<String,Object> queryAll(OperatQueryCriteria criteria, Pageable pageable){
        Page<Operat> page = operatRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        return PageUtil.toPage(page.map(operatMapper::toDto));
    }

    @Override
    public List<OperatDto> queryAll(OperatQueryCriteria criteria){
        return operatMapper.toDto(operatRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
    @Transactional
    public OperatDto findById(Integer id) {
        Operat operat = operatRepository.findById(id).orElseGet(Operat::new);
        ValidationUtil.isNull(operat.getId(),"Operat","id",id);
        return operatMapper.toDto(operat);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OperatDto create(Operat resources) {
        return operatMapper.toDto(operatRepository.save(resources));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(Operat resources) {
        Operat operat = operatRepository.findById(resources.getId()).orElseGet(Operat::new);
        ValidationUtil.isNull( operat.getId(),"Operat","id",resources.getId());
        operat.copy(resources);
        operatRepository.save(operat);
    }

    @Override
    public void deleteAll(Integer[] ids) {
        for (Integer id : ids) {
            operatRepository.deleteById(id);
        }
    }

    @Override
    public void download(List<OperatDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (OperatDto operat : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("推广人员编码", operat.getSenceNo());
            map.put("推广人员手机号", operat.getPhone());
            map.put("推广码地址 http://xxx", operat.getImg());
            map.put("推广人员姓名", operat.getName());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public ResponseEntity buildOwnQCode(Operat operat) {
        Optional<Operat> oneOptional = operatRepository.findOne(Example.of(operat));
        if (!oneOptional.isPresent()){
            return new ResponseEntity(HttpStatus.NO_CONTENT);
        }
        SyWeixToken XcxToken = weixTokenRepository.findByType("USER_XCX");
        String accesToken = XcxToken.getToken();
        HttpRequest post = HttpRequest.post("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token="+accesToken);
        JSONObject body = new JSONObject();
        body.put("page","pages/tab/index/index");
        body.put("scene", ConstKey._SenceNO+"="+operat.getSenceNo());
        body.put("check_path",true);
//        正式版为 "release"，体验版为 "trial"，开发版为 "develop"。默认是正式版
        body.put("env_version",XcxVersion);
        post.body(body.toJSONString());
        HttpResponse execute = post.execute();
        BufferedImage bufferedImage = ImgUtil.toImage(execute.bodyBytes());
        String fileName = uploadPrefix+File.separatorChar+operat.getSenceNo()+".jpg";
        String url = new StringBuilder().append(htmlImgSrc).append(fileName).toString();
        ImgUtil.write(bufferedImage,new File(properties.getPath().getPath()+fileName));
        Operat one = oneOptional.get();
        one.setImg(url);
        operatRepository.save(one);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @Override
    public void downLoadImg(HttpServletRequest request,HttpServletResponse response, String senceno) {
        File file = new File(properties.getPath().getPath() + uploadPrefix + File.separatorChar + senceno + ".jpg");
        FileUtil.downloadFile(request,response,file,false);
    }

    public static String uploadPrefix = "qrcode";
}